package com.mutual.reins.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * 再保工具类
 * @author 86152
 */
public class ReinsUtils {
    /**
     * BigDecimal 保留几位小数方法
     * @param d1 数值对象
     * @param round 小数位个数
     * @return 截取结果
     */
    public static BigDecimal scale(BigDecimal d1,Integer  round){
        return d1.setScale(round,BigDecimal.ROUND_HALF_UP);
    }
    /**
     * BigDecimal加法
     * @param d1 数值对象
     * @param d2 数值对象
     * @return 截取结果
     */
    public static BigDecimal add(BigDecimal d1, BigDecimal d2){
        if(d1.compareTo(BigDecimal.ZERO)==0){
            d1=new BigDecimal(0);
        }
        if(d2.compareTo(BigDecimal.ZERO)==0){
            d2=new BigDecimal(0);
        }
        BigDecimal b1=new BigDecimal(String.valueOf(d1));
        BigDecimal b2=new BigDecimal(String.valueOf(d2));
        return b1.add(b2);
    }
    /**
     * BigDecimal加法结果保留X位小数
     * @param d1 数值对象
     * @param d2 数值对象
     * @return 计算结果
     */
    public static BigDecimal addRound(BigDecimal d1, BigDecimal d2,Integer round){
        if(d1.compareTo(BigDecimal.ZERO)==0){
            d1=new BigDecimal(0);
        }
        if(d2.compareTo(BigDecimal.ZERO)==0){
            d2=new BigDecimal(0);
        }
        BigDecimal b1=new BigDecimal(String.valueOf(d1));
        BigDecimal b2=new BigDecimal(String.valueOf(d2));
        return b1.add(b2).setScale(round,BigDecimal.ROUND_HALF_UP);
    }
    /**
     * BigDecimal减法
     * @param d1 数值对象
     * @param d2 数值对象
     * @return 计算结果
     */
    public static BigDecimal sub(BigDecimal d1, BigDecimal d2){
        if(d1.compareTo(BigDecimal.ZERO)==0){
            d1=new BigDecimal(0);
        }
        if(d2.compareTo(BigDecimal.ZERO)==0){
            d2=new BigDecimal(0);
        }
        BigDecimal b1=new BigDecimal(String.valueOf(d1));
        BigDecimal b2=new BigDecimal(String.valueOf(d2));
        return b1.subtract(b2);
    }
    /**
     * BigDecimal减法结果保留X位小数
     * @param d1 数值对象
     * @param d2 数值对象
     * @return 计算结果
     */
    public static BigDecimal subRound(BigDecimal d1, BigDecimal d2,Integer  round){
        if(d1.compareTo(BigDecimal.ZERO)==0){
            d1=new BigDecimal(0);
        }
        if(d2.compareTo(BigDecimal.ZERO)==0){
            d2=new BigDecimal(0);
        }
        BigDecimal b1=new BigDecimal(String.valueOf(d1));
        BigDecimal b2=new BigDecimal(String.valueOf(d2));
        return b1.subtract(b2).setScale(round,BigDecimal.ROUND_HALF_UP);
    }
    /**
     * BigDecimal乘法
     * @param d1 数值对象
     * @param d2 数值对象
     * @return 计算结果
     */
    public static BigDecimal mul(BigDecimal d1,BigDecimal d2){
        if(d1.compareTo(BigDecimal.ZERO)==0){
            d1=new BigDecimal(0);
        }
        if(d2.compareTo(BigDecimal.ZERO)==0){
            d2=new BigDecimal(0);
        }
        BigDecimal b1=new BigDecimal(String.valueOf(d1));
        BigDecimal b2=new BigDecimal(String.valueOf(d2));
        return b1.multiply(b2);
    }
    /**
     * BigDecimal乘法结果保留X位小数
     * @param d1 数值对象
     * @param d2 数值对象
     * @return 计算结果
     */
    public static BigDecimal mulRound(BigDecimal d1, BigDecimal d2,Integer  round){
        if(d1.compareTo(BigDecimal.ZERO)==0){
            d1=new BigDecimal(0);
        }
        if(d2.compareTo(BigDecimal.ZERO)==0){
            d2=new BigDecimal(0);
        }
        BigDecimal b1=new BigDecimal(String.valueOf(d1));
        BigDecimal b2=new BigDecimal(String.valueOf(d2));
        return b1.multiply(b2).setScale(round,BigDecimal.ROUND_HALF_UP);
    }
    /**
     * BigDecimal除法
     * @param d1 数值对象
     * @param d2 数值对象
     * @return 计算结果
     */
    public static BigDecimal div(BigDecimal d1,BigDecimal d2){
        if(d1.compareTo(BigDecimal.ZERO)==0){
            d1=new BigDecimal(0);
        }
        if(d2.compareTo(BigDecimal.ZERO)==0){
            d2=new BigDecimal(0);
        }
        BigDecimal b1=new BigDecimal(String.valueOf(d1));
        BigDecimal b2=new BigDecimal(String.valueOf(d2));
        if(b2.equals(0)){
            return b2;
        }else{
            return b1.divide(b2,10,BigDecimal.ROUND_HALF_UP);
        }
    }
    /**
     * BigDecimal除法保留N位小数
     * @param d1 数值对象
     * @param d2 数值对象
     * @param round 小数位
     * @return 计算结果
     */
    public static BigDecimal divRound(BigDecimal d1,BigDecimal d2,Integer  round){
        if (d1.compareTo(BigDecimal.ZERO) != 0) {
        } else {
            d1=new BigDecimal(0);
        }
        if(d2.compareTo(BigDecimal.ZERO)==0){
            d2=new BigDecimal(0);
        }
        BigDecimal b1=new BigDecimal(String.valueOf(d1));
        BigDecimal b2=new BigDecimal(String.valueOf(d2));
        if(b2.compareTo(BigDecimal.ZERO)==0){
            return b2;
        }else{
            return b1.divide(b2,10,BigDecimal.ROUND_HALF_UP).setScale(round,BigDecimal.ROUND_HALF_UP);
        }
    }
    /**
     * BigDecimal比例计算
     * @param d1 参数1
     * @param d2 参数2
     * @return 结果
     */
    public static BigDecimal rateRound(BigDecimal d1,BigDecimal d2,Integer  round){
        BigDecimal b1=new BigDecimal(String.valueOf(d1));
        BigDecimal b2=new BigDecimal(String.valueOf(d2));
        return b1.divide(b2,8).multiply(new BigDecimal("100.00")).setScale(round,BigDecimal.ROUND_HALF_UP);
    }

    /**
     * BigDecimal比例计算(乘法)
     * @param d1 参数1
     * @param d2 参数2
     * @return 结果
     */
    public static BigDecimal rateMulRound(BigDecimal d1,BigDecimal d2,Integer d3,Integer  round){
        BigDecimal b1=new BigDecimal(String.valueOf(d1));
        BigDecimal b2=new BigDecimal(String.valueOf(d2));
        return b1.multiply(b2).divide(new BigDecimal(d3),8).setScale(round,BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 反射实现对象赋值
     * @param clazz 源类文件
     * @param o 目标文件
     * @return  返回处理好的类文件
     * @throws IllegalAccessException 获取文件属性权限异常
     * @throws InstantiationException
     */
    public static Object objectValueCopy(Class<?> clazz, Object o) throws IllegalAccessException, InstantiationException {
        Field[] targetFields = clazz.getDeclaredFields();
        Field[] sourceFields = o.getClass().getDeclaredFields();
        //属性名和值放入map，提高后面的赋值时的效率
        Map<String, Object> sourceData = new HashMap<String, Object>(16);
        for (Field field: sourceFields){
         //暴力破解，否则取不到值
            field.setAccessible(true);
            sourceData.put(field.getName(), field.get(o));
        }
        Object result = clazz.newInstance();
        for (Field field: targetFields){
           //暴力破解，否则放不进去值
            field.setAccessible(true);
            if (Modifier.isFinal(field.getModifiers())){
            }else{
                field.set(result, sourceData.get(field.getName()));
            }

        }
        return result;
    }

}
